package be.nvlooy.moviereminder.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import be.nvlooy.moviereminder.dto.ReleaseDateMovieDTO;
import be.nvlooy.moviereminder.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSourceAware;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import be.nvlooy.moviereminder.common.SessionMessage;
import be.nvlooy.moviereminder.entities.Collection;
import be.nvlooy.moviereminder.entities.Friendship;
import be.nvlooy.moviereminder.entities.Movie;
import be.nvlooy.moviereminder.entities.Suggestion;
import be.nvlooy.moviereminder.entities.User;
import be.nvlooy.moviereminder.exception.ServiceException;
import be.nvlooy.moviereminder.view.CoverView;

@Controller
@RequestMapping(value="/collection")
public class CollectionController extends BasicController implements MessageSourceAware {
	
	private MovieService movieService;
	private CollectionService collectionService;
	private SuggestionService suggestionService;
	private FriendshipService friendshipService;
	private MailService mailService;
    private ReleaseDateService releaseDateService;
	
	@Autowired
	public void setMovieService(MovieService movieService) {
		this.movieService = movieService;
	}
	
	@Autowired
	public void setCollectionService(CollectionService collectionService) {
		this.collectionService = collectionService;
	}
	
	@Autowired
	public void setSuggestionService(SuggestionService suggestionService) {
		this.suggestionService = suggestionService;
	}
	
	@Autowired
	public void setFriendshipService(FriendshipService friendshipService) {
		this.friendshipService = friendshipService;
	}
	
	@Autowired
	public void setMailService(MailService mailService) {
		this.mailService = mailService;
	}

	@Autowired
	public void setReleaseDateService(ReleaseDateService releaseDateService) {
		this.releaseDateService = releaseDateService;
	}
	
	
	@RequestMapping
	public String index(
			@RequestParam(value="search", required=false) String search, 
			@RequestParam(value="filter", required=false) String filter, 
			@RequestParam(value="sorton", required=false) String sortOn, 
			@RequestParam(value="sortorder", required=false) String sortOrder,
			Model model) {
		
		User user = getAuthenticatedUser();
		
		List<Collection> collection;
		Boolean filterMustsee = null;
		Boolean filterSuggested = null;
		
		if(filter != null && filter.equals("mustsee"))
			filterMustsee = true;
		if(filter != null && filter.equals("suggested"))
			filterSuggested = true;
		
		collection = collectionService.searchCollectionItems(user, search, sortOn, sortOrder, filterMustsee, filterSuggested);
		
		model.addAttribute("collection", collection);
		model.addAttribute("search", search);
		model.addAttribute("sortorder", sortOrder);
		model.addAttribute("sorton", sortOn);
		model.addAttribute("filter", filter);
		
		return "/collection/index";
	}
	
	@RequestMapping(value="/remove/{movieID}")
	public String removeFromCollection(@PathVariable int movieID, Model model) {
		User user = getAuthenticatedUser();
		Movie movie = movieService.getMovieByID(movieID);
		
		try {
			// remove movie from the collection
			collectionService.removeCollection(user, movie);
			showFrontendMessage("collectionRemovedSuccessfull", movie.getTitle());
		}
		catch(ServiceException e) {
			showFrontendMessage(e.getMessage(), SessionMessage.MessageType.ERROR, movie.getTitle());
		}
		
		return "redirect:/collection";
	}
	
	@RequestMapping(value="/info/{collectionID}")
	public String info(@PathVariable int collectionID, Model model) {
		Collection collectionItem = collectionService.getCollectionItemByID(collectionID);
		
		if(collectionItem == null) {
			showFrontendMessage("collectionItemDoesntExist", SessionMessage.MessageType.ERROR, collectionID);
			return "redirect:/collection";
		}
		
		model.addAttribute("collectionItem", collectionItem);
		return "/collection/info";
	}
	
	@RequestMapping(value="/mustsee/{collectionID}")
	public String movieMustSee(@PathVariable int collectionID, Model model) {
		User user = getAuthenticatedUser();
		collectionService.setMustSee(user, collectionID, true);
		return "redirect:/collection/info/"+String.valueOf(collectionID);
	}
	
	@RequestMapping(value="/mustnotsee/{collectionID}")
	public String movieMustNotSee(@PathVariable int collectionID, Model model) {
		User user = getAuthenticatedUser();
		collectionService.setMustSee(user, collectionID, false);
		return "redirect:/collection/info/"+String.valueOf(collectionID);
	}
	
	@RequestMapping(value="/cover/{movieID}")
	public ModelAndView showCover(@PathVariable int movieID, Model model) {
		Movie movie = movieService.getMovieByID(movieID);
		
		model.addAttribute("cover", movie.getCover());
		ModelAndView mav = new ModelAndView(new CoverView());

		return mav;
	}
	
	@RequestMapping(value="/suggest/{collectionID}/{friendshipID}")
	public String newSuggestion(@PathVariable int collectionID, 
			@PathVariable int friendshipID, 
			Model model) {
		
		User user = getAuthenticatedUser();
		Friendship friendship = friendshipService.getFriendshipByID(friendshipID);
		Collection collection = collectionService.getCollectionItemByID(collectionID);
		
		try {
			Suggestion suggestion = suggestionService.newSuggestion(user, friendship.getFriend(), collection.getMedia());
			showFrontendMessage("newSuggestionSuccess", friendship.getFriend().getFullName());
			
			// send a suggestion mail to the friend
			Map<String, Object> mailData = new HashMap<String, Object>();
			mailData.put("friendship", friendship);
			mailData.put("suggestion", suggestion);
			mailData.put("media", collection.getMedia());
			mailService.sendMessage(friendship.getFriend().getEmail(), 
					getMessage("mailSubjectNewSuggestion", user.getFullName()), 
					"newSuggestion", 
					mailData);
		}
		catch(ServiceException ex) {
			showFrontendMessage(ex.getMessage(), SessionMessage.MessageType.ERROR);
		}
		
		return "redirect:/collection/info/"+String.valueOf(collectionID);
	}

   	@RequestMapping(value="/findreleasedate/{collectionId}")
	public String findReleaseDateAjax(@PathVariable int collectionId, Model model) {
        Collection collectionItem = collectionService.getCollectionItemByID(collectionId);

        List<ReleaseDateMovieDTO> result = releaseDateService.findMoviesByTitle(collectionItem.getMedia().getTitle());
        model.addAttribute("result", result);

        return "/collection/ajax_releasedate";
	}
}
